<html>
    <head>
        <title>传统加载方式与 ES_Modules混用</title>
    </head>
    <body>
        <script>
             /*
                传统加载方式与ES Modules的混用

                            在ABP的Razor Pages 中可以使用 Webpack打包直接使用ES Modules，
                            
                            并且这种方式不会影响原有的传统JavaScript加载方式 (如全局变量 、RequireJS等)


            */

            /*
                   一、 ES Modules 与传统脚本的隔离性

                                     ES Modules 与传统<script>脚本具有以下隔离特性：
                                        
                                     ①、作用域独立： 
                                            
                                               ES Modules: 每个模块都有自己独立的作用域，不会污染全局变量

                                               传统脚本：  默认将变量和函数添加到全局作用域  (window对象)

                                     ②、加载方式不同：

                                                ES Modules : 使用 <script type="module"> ,支持 import/export语法

                                                传统脚本：  默认同步加载，支持 require()  （如果已经引入 RequireJS的前提下 AMD异步模块加载）

                                     ③、执行时机不同：

                                                ES Modules： 默认异步加载(defer特性默认为true)，按顺序执行

                                                传统脚本：  按文档顺序同步执行 (除非使用async属性)

            */


            /*
                      二、混用示例：

                                    在同一个Razor Page 中可以同时使用 ES Modules和 传统脚本：

                                            -- Razor Page --
                                            @section Scripts {

                                                    -- 传统脚本：使用RequireJS --
                                                    <script src="~/lib/requirejs/require.js"></、script>
                                                    <script>
                                                        require(['moduleA', 'moduleB'], function(a, b) {
                                                            // RequireJS加载模块
                                                        });
                                                    </、script>
                                                    
                                                    -- ES Modules：使用import/export --
                                                    <script type="module">
                                                        import { fetchData } from '~/js/data-service.js';
                                                        
                                                        document.addEventListener('DOMContentLoaded', async () => {
                                                            const data = await fetchData();
                                                            console.log(data);
                                                        });
                                                    </、script>
                                                    
                                                    -- 传统脚本：全局变量方式 --
                                                    <script src="~/js/legacy-script.js"></、script>
                                            }   


            */


            /*
                  三、潜在冲突与解决方案

                                    <1>、全局变量命名冲突

                                            如果ES 模块中不小心声明了全局变量，可能与传统脚本冲突：

                                                  // ES 模块中避免这样做

                                                  window.myGlobalVar='冲突'、

                                                  // 推荐使用模块作用域
                                                  const myLocalVar ='安全'
                                                  export const myFunction=()=>{ };


                                    <2>、RequireJS 与 ES Modules 共存

                                            如果项目中同时使用RequireJS 与 ES Modules,需要注意：

                                                ①、RequireJS 使用require()加载模块

                                                ②、ES Modules 使用import语法

                                                ③、两者互不干扰，但加载顺序可能需要控制


                                    <3>、Monaco编辑器的特殊情况

                                                Monaco 编辑器默认使用 AMD模块格式(RequireJS支持的模式)，但也可以通过ES Modules加载：

                                                    // 使用ES Modules加载Monaco（需要正确配置路径）
                                                    <script type="module">
                                                        import * as monaco from 'monaco-editor/esm/vs/editor/editor.main.js';
                                                        
                                                        // 创建编辑器
                                                        monaco.editor.create(...);
                                                    </、script>


                                    <4>、最佳实践：

                                               1. 明确划分代码边界
                                                        将新代码写成 ES 模块，保持独立
                                                        旧代码继续使用传统方式，逐步迁移

                                               2、使用命名空间避免冲突

                                                        在传统脚本中使用命名空间：

                                                        // 传统脚本
                                                        var MyLegacyLibrary = {
                                                            init: function() {  
                                                            
                                                            }
                                                        };

                                               3. 优先使用 ES Modules

                                                        对于新项目或新功能，推荐使用 ES Modules：

                                                        // ES模块
                                                        export const MyModernLibrary = {
                                                            init: () => { 
                                                            
                                                            }
                                                        };

                                                4、根据环境现在加载方式：

                                                        <script>
                                                            // 传统脚本检测
                                                            if (typeof MyLegacyLibrary !== 'undefined') {
                                                                MyLegacyLibrary.init();
                                                            }
                                                        </、script>

                                                        <script type="module">
                                                            // ES模块加载
                                                            import { MyModernLibrary } from './modern-library.js';
                                                            MyModernLibrary.init();
                                                        </、script>                                       
            */

            /*
                        四、总结 

                                            在 ABP 的 Razor Pages 中混用 ES Modules 和传统脚本是安全的，因为：

                                                1、作用域隔离：
                                                    
                                                        ES 模块不会污染全局作用域

                                                2、加载机制独立：
                                                    
                                                        type="module"与传统脚本互不干扰
                                                
                                                3、执行顺序可控：
                                                
                                                        通过defer和async属性控制加载顺序


                                            只要遵循最佳实践，就可以在不影响现有功能的前提下引入现代 JavaScript 模块系统。

            */
        </script>
    </body>
</html>